let targetMap = new WeakMap();

let activeEffect = null;

function watchEffect(eff) {
  activeEffect = eff;
  activeEffect();
  activeEffect = null;
}

function track(target, key) {
  if (!activeEffect) return;
  let depsMap = targetMap.get(target);
  if (!depsMap) {
    targetMap.set(target, (depsMap = new Map()));
  }
  let dep = depsMap.get(key);
  if (!dep) {
    depsMap.set(key, (dep = new Set()));
  }
  dep.add(activeEffect);
}

function trigger(target, key) {
  const depsMap = targetMap.get(target);
  if (!depsMap) return;
  let dep = depsMap.get(key);
  if (dep) {
    dep.forEach((effect) => {
      effect();
    });
  }
}

function reactive(target) {
  const handler = {
    get(target, key, receiver) {
      let result = Reflect.get(target, key, receiver);
      track(target, key);
    },
    set(target, key, value, receiver) {
      let oldValue = target[key];
      let result = Reflect.set(target, key, value, receiver);
      if (oldValue != value) {
        trigger(target, key);
      }
      return result;
    },
  };
}

function ref(raw) {
  let r = {
    get value() {
      track(r, "value");
      return raw;
    },
    set value(newValue) {
      if (newValue != raw) {
        raw = newValue;
        trigger(r, "value");
      }
    },
  };
  return r;
}

function computed(getter) {
  let result = ref();
  watchEffect(() => {
    result.value = getter();
  });
  return result;
}

const state = reactive({count:0})
watchEffect(()=>{
  console.log('===> reactivity.js:79 ~ state.count', state.count);
})

num.value = 20;
const double = computed(()=>state.count * 2)

